package com.share51.novel.service;

import com.share51.novel.config.http.HttpProxy;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpRequestBase;
import org.springframework.scheduling.annotation.Async;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.LinkedList;
import java.util.Queue;

/**
 * http请求操作类
 * @author gb
 */
public interface HttpClientService {

    String USER_AGENT="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36";

    Queue<HttpProxy> PROXY_QUEUE=new LinkedList<>();

    HttpProxy HTTP_PROXY=new HttpProxy();

    int PROXY_POOL_MIN_SIZE=10;

    /**
     * 是否启用 ip 代理
     * @return
     */
    default boolean enableProxy(){
        return false;
    }

    /**
     * 默认的获取 http 请求的 config 主要用来配置代理
     * @return
     * @throws IOException
     */
    default RequestConfig getConfig() throws IOException {
        RequestConfig.Builder builder = RequestConfig
                .custom()
                .setConnectTimeout(1000*30)
                .setSocketTimeout(1000*30)
                .setConnectionRequestTimeout(1000*30);
        // 获取 代理
        if (enableProxy()){
            if (StringUtils.isBlank(HTTP_PROXY.getIp())){
                changeProxy();
            }else {
                HttpHost proxy = new HttpHost(HTTP_PROXY.getIp(), HTTP_PROXY.getPort());
                builder.setProxy(proxy);
            }
        }
        return builder.build();
    }

    /**
     * 设置请求头
     * @param httpMethod
     */
    default void setHttpHeaders(HttpRequestBase httpMethod){
        URI uri = httpMethod.getURI();
        if (uri!=null){
            String host = uri.getHost();
            int port= uri.getPort();
            String protocol = uri.getScheme();
            String referer = protocol + "://" + host + (port==-1?"":":"+port);
            httpMethod.setHeader("Referer", referer);
        }
        httpMethod.setHeader("Upgrade-Insecure-Requests", "1");
        httpMethod.setHeader("User-Agent",USER_AGENT);
        httpMethod.setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8");
        httpMethod.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
    }

    /**
     * 初始化 爬取 代理数据
     * @throws IOException
     */
    @Async
    void initProxy() throws IOException;

    /**
     * 处理 http get 请求
     * @param url 请求的url
     * @return 响应的结果
     * @throws IOException
     */
    String doGet(String url) throws IOException;

    /**
     * 下载文件
     * @param url 要下载的文件url
     * @throws IOException
     * @return
     */
    ByteArrayOutputStream downloadFile(String url) throws IOException;

    /**
     * 切换代理
     * @throws IOException
     */

    default void changeProxy() throws IOException {
        HttpProxy httpProxy = PROXY_QUEUE.poll();
        if (httpProxy==null){
            this.initProxy();
        }else {
            HTTP_PROXY.setIp(httpProxy.getIp());
            HTTP_PROXY.setPort(httpProxy.getPort());
            if (PROXY_QUEUE.size()<=PROXY_POOL_MIN_SIZE){
                // 代理池不够了，需要添加了
                this.initProxy();
            }
        }

    }
}
